home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / hdebug.zip / HDEBUG10.PAS < prev    next >
Pascal/Delphi Source File  |  1991-10-20  |  6KB  |  188 lines

  1.  
  2. Unit HDebug10;
  3.  
  4. {$O-}    {  The routines Allocation and Deallocation are called through
  5.             pointers to their addresses.  If you have to overlay, place
  6.             these two procedures in a non-overlaid unit of their own.        }
  7.  
  8. {----------------------------------------------------------------------------}
  9.  
  10. interface
  11.  
  12.   uses
  13.     CRT,       {  color constants   }
  14.     Heap,      {  Heap Interceptor  }
  15.     MapInfo;
  16.  
  17.   var
  18.     HDMessage : String;       {  WATCH this variable for more information.   }
  19.  
  20.     {  Heap request interrupt handlers  }
  21.  
  22. {$F+}
  23.   Procedure Allocating(Size : Word; BlockAddr,CallAddr : Pointer);
  24.   Procedure Deallocating(Size : Word; BlockAddr,CallAddr : Pointer);
  25. {$F-}
  26.  
  27. {----------------------------------------------------------------------------}
  28.  
  29. implementation
  30.  
  31. const
  32.   VideoSegment = $B800;           {  $B000 for monochrome monitors.          }
  33.   HeapGranularity = 8;            {  Turbo Pascal 6.0 heap granularity.      }
  34.  
  35. var
  36.   HeapSize,                       {  Used to calculate the size of the heap  }
  37.   HeapBottom,                     {  and the position of pointers within it. }
  38.   HeapTop : LongInt;
  39.   NumHeapPointers : Word;
  40.  
  41.   UserHeapCount,                  {  Counts heap variables created.          }
  42.   Reference : Word;               {  Incremented with each heap interception.}
  43.  
  44. {----------------------------------------------------------------------------}
  45.  
  46.     {  Represent an integer as a string.  }
  47.  
  48.   Function IntStr(A : Integer) : String;
  49.     var
  50.       Temp : String;
  51.     Begin
  52.       Str(A,Temp);
  53.       IntStr := Temp;
  54.     End;
  55.  
  56. {----------------------------------------------------------------------------}
  57.  
  58.     {  Represent a pointer as a string.  }
  59.  
  60. Function PointerStr(P : Pointer) : String;
  61.   Begin
  62.     PointerStr := 'PTR('+HexPtrStr(P)+')';
  63.   End;
  64.  
  65. {----------------------------------------------------------------------------}
  66.  
  67.     {  Convert a pointer to a longint.  }
  68.  
  69. Function Pointer_To_LongInt(P : Pointer) : LongInt;
  70.   type
  71.     PtrRec = record
  72.       Lo,Hi : Word;
  73.     end;
  74.   Begin
  75.     Pointer_To_LongInt := LongInt(PtrRec(P).Hi)*16+PtrRec(P).Lo;
  76.   End;
  77.  
  78. {----------------------------------------------------------------------------}
  79.  
  80.     {  Display an urgent message on the screen or in the debugger.
  81.        If a string begins with an '!', it will be displayed on the screen.   }
  82.  
  83. Procedure Message(S : String);
  84.   const
  85.     MessageAttr = Red*16+Yellow;          {  Attention getting, ugly colors. }
  86.   var
  87.     SaveLine : Array[1..255] of Word;     {  Used to restore the screen.     }
  88.     VideoLine : Array[1..255] of Word absolute VideoSegment:0;
  89.                                           {  First video line.               }
  90.     i,L : Byte;
  91.   Begin
  92.     if (S[1] = '!') then                  {  If urgent, place on the screen. }
  93.       begin
  94.         L := Length(S);
  95.         Move(VideoLine,SaveLine,L*SizeOf(Word));
  96.         for i := 1 to L-1 do
  97.           VideoLine[i] := MessageAttr*256+Byte(S[i+1]);
  98.         ReadLn;
  99.         Move(SaveLine,VideoLine,L*SizeOf(Word));  {  Restore the screen.     }
  100.       end
  101.     else
  102.       HDMessage := S;
  103.   End;
  104.  
  105. {----------------------------------------------------------------------------}
  106.  
  107.     {  Map a pointer within the heap onto the heap map.  }
  108.  
  109. Function HeapPointer_Ordinate(P : Pointer) : LongInt;
  110.   var
  111.     HeapPointer : LongInt;
  112.   Begin
  113.     if (P = nil) then
  114.       HeapPointer_Ordinate := 0
  115.     else
  116.       begin
  117.         HeapPointer := Pointer_To_LongInt(P);
  118.         if ((HeapPointer >= HeapBottom) and (HeapPointer <= HeapTop)) then
  119.           HeapPointer_Ordinate := (HeapPointer div HeapGranularity)-
  120.                                   (HeapBottom div HeapGranularity)+1
  121.         else
  122.           Message('!'+PointerStr(P)+' is not within the heap.');
  123.       end;
  124.   End;
  125.  
  126. {----------------------------------------------------------------------------}
  127.  
  128. Procedure Allocating(Size : Word; BlockAddr,CallAddr : Pointer);
  129.   var
  130.     OldReference : Word;
  131.     Ordinate : LongInt;
  132.     Allocate : Boolean;
  133.   Begin
  134.     Inc(UserHeapCount);
  135.     Inc(Reference);
  136.     if FatalHeapError and InterceptFatalHeapErrors then
  137.       begin
  138.         Message('!Allocation error detected.');
  139.         Enter_Debugger(CallAddr);
  140.         Message('!Found in unit '+UnitName+', line '+IntStr(CurrentLineNumber)+', address '+PointerStr(CallAddr));
  141.       end;
  142.   End;
  143.  
  144. {----------------------------------------------------------------------------}
  145.  
  146. Procedure Deallocating(Size : Word; BlockAddr,CallAddr : Pointer);
  147.   var
  148.     Ordinate : LongInt;
  149.     Original_Size : Word;
  150.     Deallocate : Boolean;
  151.  
  152.   Begin
  153.     Dec(UserHeapCount);
  154.     Inc(Reference);
  155.     if FatalHeapError and InterceptFatalHeapErrors then
  156.       begin
  157.         Message('!Deallocation error detected.');
  158.         Enter_Debugger(CallAddr);
  159.         Message('!Found in unit '+UnitName+', line '+IntStr(CurrentLineNumber)+', address '+PointerStr(CallAddr));
  160.       end;
  161.   End;
  162.  
  163. {----------------------------------------------------------------------------}
  164.  
  165. BEGIN
  166.  
  167.     {  Assign procedures to each of the interrupt handlers.  }
  168.  
  169.   Allocation_Handler   := @Allocating;
  170.   Deallocation_Handler := @Deallocating;
  171.  
  172.     {  Initialize  }
  173.  
  174.   UserHeapCount := 0;
  175.   Reference     := 0;
  176.  
  177.     {  Get the dimensions of the heap as soon as possible.  }
  178.  
  179.   HeapBottom      := Pointer_To_LongInt(HeapOrg);
  180.   HeapTop         := Pointer_To_LongInt(HeapEnd);
  181.   HeapSize        := HeapTop-HeapBottom;
  182.   NumHeapPointers := HeapSize div HeapGranularity;
  183.  
  184.   HDMessage := '';
  185. END.
  186.  
  187. {----------------------------------------------------------------------------}
  188.